package com.blog4j.gateway.filter;

import com.alibaba.fastjson.JSONObject;
import com.blog4j.common.enums.ErrorEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

/**
 * @author 98k灬
 * @version v1.0.0
 * @Description : 功能描述
 * @Create on : 2024/8/25 18:20
 **/
@Component
@Slf4j
public class AuthorizationFilter implements GlobalFilter, Ordered {
    private static final String API = "/api";
    private static final String AUTHENTICATION = "Authentication";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 请求对象
        ServerHttpRequest request = exchange.getRequest();
        // 响应对象
        ServerHttpResponse response = exchange.getResponse();
        // 获取token
        String token = request.getHeaders().getFirst(AUTHENTICATION);
        String path = request.getPath().pathWithinApplication().value();
        log.info("request path: [{}]", path);
        if (path.contains(API)) {
            log.info("api request .");
            return chain.filter(exchange);
        }

        if (StringUtils.isBlank(token)) {
            log.error("token is null .");
            return writeResponse(response, ErrorEnum.EMPTY_LOGIN_TOKEN.getErrorMsg());
        }

        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 1;
    }

    private Mono<Void> writeResponse(ServerHttpResponse response, String message) {
        JSONObject result = new JSONObject();
        result.put("code", ErrorEnum.EMPTY_LOGIN_TOKEN.getErrorCode());
        result.put("message", message);
        // 转换响应消息内容对象为字节
        byte[] bits = result.toJSONString().getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = response.bufferFactory().wrap(bits);
        // 设置响应对象状态码 401
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        // 设置响应对象内容并且指定编码，否则在浏览器中会中文乱码
        response.getHeaders().add(HttpHeaders.CONTENT_TYPE,  "application/json;charset=UTF-8");
        return response.writeWith(Mono.just(buffer));
    }
}
